package com.ywk.miaohsa.service;

import com.ywk.miaohsa.common.Constants;
import com.ywk.miaohsa.common.GeneralMethod;
import com.ywk.miaohsa.dao.MiaoshaUserDao;
import com.ywk.miaohsa.dao.UserDao;
import com.ywk.miaohsa.domain.MiaoshaUser;
import com.ywk.miaohsa.domain.User;
import com.ywk.miaohsa.exception.GlobalException;
import com.ywk.miaohsa.redis.MiaoshaUserKey;
import com.ywk.miaohsa.redis.RedisService;
import com.ywk.miaohsa.result.CodeMsg;
import com.ywk.miaohsa.util.MD5Util;
import com.ywk.miaohsa.util.UUIDUtil;
import com.ywk.miaohsa.vo.LoginVo;
import com.ywk.miaohsa.vo.MiaoshaUserVo;
import com.ywk.miaohsa.vo.PasswordVo;
import com.ywk.miaohsa.vo.UserInfoVo;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

@Service
public class MiaoshaUserService {

    public static final String COOKI_NAME_TOKEN = "token";

    @Autowired
    MiaoshaUserDao miaoshaUserDao;

    @Autowired
    UserDao userDao;

    @Autowired
    RedisService redisService;

    //缓存里存了两个同一用户两个user对象，一个是有时间限制的session；另一个是永久有效的，需跟数据库数据保持一致
    public MiaoshaUserVo login(HttpServletResponse response, LoginVo loginVo) {
        MiaoshaUserVo userVo=new MiaoshaUserVo();
        if(loginVo==null){
            throw new GlobalException(CodeMsg.SERVER_ERROR);
        }
        String mobile = loginVo.getMobile();
        String formPass = loginVo.getPassword();
        //判断手机号
        MiaoshaUser user = getById(Long.parseLong(mobile));
        if(user==null){
            throw new GlobalException(CodeMsg.MOBILE_NOT_EXIST);
        }
        //判断密码
        String dbPass=MD5Util.formPassToDBPass(formPass,user.getSalt());
        if(!dbPass.equals(user.getPassword())){
            throw new GlobalException(CodeMsg.PASSWORD_ERROR);
        }
        String token = UUIDUtil.uuid();
        //分布式session
        addCookie(response,user,token);
        userVo.setToken(token);
        userVo.setName(user.getNickname());
        userVo.setPhoneNum(String.valueOf(user.getId()));
        userVo.setAddress(user.getAddress());
        return userVo;
    }

    public MiaoshaUser getById(long id){
        //取缓存
        MiaoshaUser user=redisService.get(MiaoshaUserKey.id,""+id,MiaoshaUser.class);
        if(user==null){
            //取数据库
            user=miaoshaUserDao.getById(id);
            if(user!=null){
                redisService.set(MiaoshaUserKey.id,""+id,user);
            }
        }
        return user;
    }

    private void addCookie(HttpServletResponse response, MiaoshaUser user, String token) {
        //塞缓存（服务端），将cookie塞到response返回（客户端）
        redisService.set(MiaoshaUserKey.token,token,user);//key:MiaoshaUserKey:tk3b637712944e47f9a1efb3b08e65da48
        Cookie cookie=new Cookie(COOKI_NAME_TOKEN,token);
        //此属性（有效期）不设置cookie只保存到浏览器，关闭浏览器cookie将失效，设置了，则cookie将一定时间保存在硬盘
        cookie.setMaxAge(MiaoshaUserKey.TOKEN_EXPIRE);
        cookie.setPath("/");//设置该cookie与资源路径绑定（"/"代表网站根路径），即整个网站页面跳转都有效
        response.addCookie(cookie);//将cookie塞到response返回客户端
    }

    @Transactional
    public void register(LoginVo loginVo) {
        //判断入参
        if(loginVo==null){
            throw new GlobalException(CodeMsg.SERVER_ERROR);
        }
        //判断手机号是否已注册过
        String mobile=loginVo.getMobile();
        MiaoshaUser miaoshaUser = getById(Long.parseLong(mobile));
        if(miaoshaUser!=null){
            throw new GlobalException(CodeMsg.MOBILE_EXIST);
        }
        //注册
        String formPass = loginVo.getPassword();
        String dbPass=MD5Util.formPassToDBPass(formPass,Constants.SALT);
        User user=new User();
        user.setPhoneNum(mobile);
        user.setPassword(dbPass);
        userDao.insert(user);
        miaoshaUser.setFlagId(UUIDUtil.getFlagUUID());
        miaoshaUser.setId(Long.valueOf(mobile));
        miaoshaUser.setPassword(dbPass);
        miaoshaUserDao.insert(miaoshaUser);
    }

    public UserInfoVo modifyUserInfo(HttpServletRequest request, MiaoshaUser miaoshaUser, UserInfoVo userVo) {
        if (miaoshaUser==null) {
            throw new GlobalException(CodeMsg.REQUEST_ILLEGAL);
        }
        long id=miaoshaUser.getId();
        //先更新数据库
        miaoshaUser.setId(Long.valueOf(userVo.getPhoneNum()));
        miaoshaUser.setNickname(userVo.getName());
        miaoshaUser.setAddress(userVo.getAddress());
        miaoshaUserDao.updateUserInfo(miaoshaUser);
        //处理缓存
        redisService.delete(MiaoshaUserKey.id,""+id);
        String token=GeneralMethod.getCookieValue(request,COOKI_NAME_TOKEN);
        redisService.delete(MiaoshaUserKey.token,token);
        redisService.set(MiaoshaUserKey.token,token,miaoshaUser);
        UserInfoVo userInfoVo=new UserInfoVo();
        userInfoVo.setName(miaoshaUser.getNickname());
        userInfoVo.setPhoneNum(miaoshaUser.getId()+"");
        userInfoVo.setAddress(miaoshaUser.getAddress());
        return userInfoVo;
    }

    public MiaoshaUser getByToken(HttpServletResponse response, String token) {
        if (StringUtils.isEmpty(token)) {
            return null;
        }
        MiaoshaUser miaoshaUser=redisService.get(MiaoshaUserKey.token,token,MiaoshaUser.class);
        //延长有效期
        if (miaoshaUser != null) {
            addCookie(response,miaoshaUser,token);
        }
        return miaoshaUser;
    }

    @Transactional
    public void modifyPassword(HttpServletRequest request,MiaoshaUser miaoshaUser,PasswordVo psw) {
        if (miaoshaUser==null) {
            throw new GlobalException(CodeMsg.REQUEST_ILLEGAL);
        }
        String dbOldPsw=MD5Util.formPassToDBPass(psw.getOldPsw(),Constants.SALT);
        String dbNewPsw=MD5Util.formPassToDBPass(psw.getNewPsw(),Constants.SALT);
        if(!miaoshaUser.getPassword().equals(dbOldPsw)){
            throw new GlobalException(CodeMsg.OLD_PASSWORD_ERROR);
        }
        miaoshaUser.setPassword(dbNewPsw);
        miaoshaUserDao.modifyPsw(miaoshaUser);
        User user=new User();
        user.setPhoneNum(String.valueOf(miaoshaUser.getId()));
        user.setPassword(dbNewPsw);
        userDao.modifyPsw(user);
        //更新缓存
        redisService.delete(MiaoshaUserKey.id,""+miaoshaUser.getId());
        String token=GeneralMethod.getCookieValue(request,COOKI_NAME_TOKEN);
        redisService.delete(MiaoshaUserKey.token,token);
        redisService.set(MiaoshaUserKey.id,""+miaoshaUser.getId(),miaoshaUser);
        redisService.set(MiaoshaUserKey.token,token,miaoshaUser);
    }

}
